#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "unity.h"
#include "uart_getData.h"
#include "mock_uart_inc.h"


// 被测函数声明
extern u32 uart_getData(u8 *rcvData, u32 len);
extern XGpio gpio_kl202;

// 测试夹具设置
void setUp(void)
{
    // 每个测试用例执行前的初始化
    // 重置所有mock的期望调用
}

void tearDown(void)
{
    // 每个测试用例执行后的清理
    // 验证所有期望的调用都已完成
}

/**
 * 测试用例1: 正常读取数据
 * Description: 当GPIO有数据且请求长度合理时，应该正确读取数据
 */
void test_uart_getData_Should_ReadData_When_DataAvailable(void)
{
    // Arrange
    u8 testData[10] = {0};
    u8 expectedData[10] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA};
    u32 requestLen = 10;
    u32 expectedLen = 10;
    
    // Mock GPIO读取返回有数据
    XGpio_DiscreteRead_ExpectAndReturn(&gpio_kl202, GPIO_KL202_READ_CH, 1);
    
    // Mock GPIO写操作（发送正脉冲）
    XGpio_DiscreteWrite_Expect(&gpio_kl202, GPIO_KL202_WRITE_CH, 1);
    XGpio_DiscreteWrite_Expect(&gpio_kl202, GPIO_KL202_WRITE_CH, 0);
    
    // Mock BRAM读取操作
    for (u32 i = 0; i < requestLen; i++)
    {
        XBram_ReadReg_ExpectAndReturn(BRAM_BASE, (i * 4), expectedData[i]);
    }
    
    // Act
    u32 result = uart_getData(testData, requestLen);
    
    // Assert
    TEST_ASSERT_EQUAL(expectedLen, result);
    TEST_ASSERT_EQUAL_UINT8_ARRAY(expectedData, testData, expectedLen);
}

/**
 * 测试用例2: 请求长度超过最大限制
 * Description: 当请求长度超过UART_KL202_RCV_DATA_LEN时，应该截断到最大长度
 */
void test_uart_getData_Should_TruncateLength_When_RequestLengthExceedsMax(void)
{
    // Arrange
    u8 testData[400] = {0};
    u32 requestLen = 400;  // 超过最大长度320
    u32 expectedLen = UART_KL202_RCV_DATA_LEN;
    
    // Mock GPIO读取返回有数据
    XGpio_DiscreteRead_ExpectAndReturn(&gpio_kl202, GPIO_KL202_READ_CH, 1);
    
    // Mock GPIO写操作（发送正脉冲）
    XGpio_DiscreteWrite_Expect(&gpio_kl202, GPIO_KL202_WRITE_CH, 1);
    XGpio_DiscreteWrite_Expect(&gpio_kl202, GPIO_KL202_WRITE_CH, 0);
    
    // Mock BRAM读取操作，只读取最大长度的数据
    for (u32 i = 0; i < expectedLen; i++)
    {
        XBram_ReadReg_ExpectAndReturn(BRAM_BASE, (i * 4), (u8)(i + 1));
    }
    
    // Act
    u32 result = uart_getData(testData, requestLen);
    
    // Assert
    TEST_ASSERT_EQUAL(expectedLen, result);
    // 验证超过最大长度的部分没有被访问
    for (u32 i = expectedLen; i < requestLen; i++)
    {
        TEST_ASSERT_EQUAL(0, testData[i]);
    }
}

/**
 * 测试用例3: 无数据可读取
 * Description: 当GPIO返回无数据时，应该立即返回0而不执行后续操作
 */
void test_uart_getData_Should_ReturnZero_When_NoDataAvailable(void)
{
    // Arrange
    u8 testData[10] = {0};
    u8 originalData[10] = {0};
    u32 requestLen = 10;
    u32 expectedLen = 0;
    
    // 保存原始数据用于比较
    memcpy(originalData, testData, sizeof(testData));
    
    // Mock GPIO读取返回无数据
    XGpio_DiscreteRead_ExpectAndReturn(&gpio_kl202, GPIO_KL202_READ_CH, 0);
    
    // 不应该调用GPIO写操作和BRAM读取操作
    
    // Act
    u32 result = uart_getData(testData, requestLen);
    
    // Assert
    TEST_ASSERT_EQUAL(expectedLen, result);
    // 验证数据缓冲区内容没有改变
    TEST_ASSERT_EQUAL_UINT8_ARRAY(originalData, testData, sizeof(testData));
}

/**
 * 测试用例4: 请求长度为0
 * Description: 当请求长度为0时，应该返回0且不执行任何读取操作
 */
void test_uart_getData_Should_ReturnZero_When_RequestLengthIsZero(void)
{
    // Arrange
    u8 testData[10] = {0};
    u8 originalData[10] = {0};
    u32 requestLen = 0;
    u32 expectedLen = 0;
    
    // 保存原始数据用于比较
    memcpy(originalData, testData, sizeof(testData));
    
    // Mock GPIO读取返回有数据
    XGpio_DiscreteRead_ExpectAndReturn(&gpio_kl202, GPIO_KL202_READ_CH, 1);
    
    // Mock GPIO写操作（即使长度为0也会执行）
    XGpio_DiscreteWrite_Expect(&gpio_kl202, GPIO_KL202_WRITE_CH, 1);
    XGpio_DiscreteWrite_Expect(&gpio_kl202, GPIO_KL202_WRITE_CH, 0);
    
    // 不应该调用BRAM读取操作
    
    // Act
    u32 result = uart_getData(testData, requestLen);
    
    // Assert
    TEST_ASSERT_EQUAL(expectedLen, result);
    // 验证数据缓冲区内容没有改变
    TEST_ASSERT_EQUAL_UINT8_ARRAY(originalData, testData, sizeof(testData));
}

/**
 * 测试用例5: 边界条件 - 最大长度
 * Description: 当请求长度等于最大长度时，应该正确读取所有数据
 */
void test_uart_getData_Should_ReadAllData_When_RequestLengthEqualsMax(void)
{
    // Arrange
    u8 testData[UART_KL202_RCV_DATA_LEN] = {0};
    u32 requestLen = UART_KL202_RCV_DATA_LEN;
    u32 expectedLen = UART_KL202_RCV_DATA_LEN;
    
    // Mock GPIO读取返回有数据
    XGpio_DiscreteRead_ExpectAndReturn(&gpio_kl202, GPIO_KL202_READ_CH, 1);
    
    // Mock GPIO写操作（发送正脉冲）
    XGpio_DiscreteWrite_Expect(&gpio_kl202, GPIO_KL202_WRITE_CH, 1);
    XGpio_DiscreteWrite_Expect(&gpio_kl202, GPIO_KL202_WRITE_CH, 0);
    
    // Mock BRAM读取操作
    for (u32 i = 0; i < requestLen; i++)
    {
        XBram_ReadReg_ExpectAndReturn(BRAM_BASE, (i * 4), (u8)(i & 0xFF));
    }
    
    // Act
    u32 result = uart_getData(testData, requestLen);
    
    // Assert
    TEST_ASSERT_EQUAL(expectedLen, result);
    // 验证前几个和后几个数据点
    TEST_ASSERT_EQUAL(0, testData[0]);
    TEST_ASSERT_EQUAL(0xFF, testData[255]);
    TEST_ASSERT_EQUAL(0x7F, testData[127]);
}